package com.gph.saviorframework.security.web.controller;

import com.alibaba.fastjson.JSONArray;
import com.gph.saviorframework.Constants;
import com.gph.saviorframework.SaviorFrameworkException;
import com.gph.saviorframework.common.model.Position;
import com.gph.saviorframework.security.service.OrgService;
import com.gph.saviorframework.security.service.PositionService;
import com.gph.saviorframework.security.service.RoleService;
import com.gph.saviorframework.util.RequestUtil;
import com.gph.saviorframework.util.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/" + Constants.FRAMEWORK_REQUEST_PATH + "/position")
public class PositionController {

    /** 日志输出 */
    final Logger logger = LoggerFactory.getLogger(PositionController.class);

    /** 领域对象名称 */
    private static final String domain = Position.class.getSimpleName().toLowerCase();

    /** 视图前缀 */
    private final String viewPrefix = Constants.FRAMEWORK_REQUEST_PATH + "/" + Constants.MODULE_CATEGORY_SECURITY + "/" + domain + "/" + domain + "_";

    @Autowired
    private PositionService positionService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private RoleService roleService;

    @Autowired
    protected SecurityUtils securityUtils;

    @Autowired
    protected MessageSourceAccessor messages;

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list() throws SaviorFrameworkException {
        return viewPrefix + "list";
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public String list(
            @RequestParam(value = Constants.DEFAULT_PAGE_MODEL_KEY, required = false, defaultValue = Constants.DEFAULT_PAGE_START) Integer start,
            @RequestParam(value = Constants.DEFAULT_RECORD_MODEL_KEY, required = false, defaultValue = Constants.DEFAULT_PAGE_SIZE) Integer limit,
            @RequestParam(value = Constants.DEFAULT_SORT_MODEL_KEY, required = false, defaultValue = Constants.DEFAULT_SORT_FIELD) String sort,
            @RequestParam(value = Constants.DEFAULT_DIR_MODEL_KEY, required = false, defaultValue = Constants.DEFAULT_SORT_DIRECTION) String dir,
            HttpServletRequest request) throws SaviorFrameworkException {
        String json = null;
        Map<String, Object> params = RequestUtil.getQueryMap(request, positionService.getFields());
        try {
            json = com.alibaba.fastjson.JSONArray.toJSONString(positionService.find(start,limit,sort,dir,params));
            logger.info(messages.getMessage("log.info.list", new String[] { securityUtils.getUserFullName(), messages.getMessage(domain) }));
        }
        catch (DataAccessException e) {
            e.printStackTrace();
            logger.error(messages.getMessage("log.error.list", new String[] { securityUtils.getUserFullName(), messages.getMessage(domain) }));
        }
        return json;
    }

    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String createPage() throws SaviorFrameworkException {
        return viewPrefix + "create";
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public @ResponseBody
    ModelMap save(@ModelAttribute Position position, HttpServletRequest request) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            securityUtils.setCreateEntity(position);// 设置新建数据的操作用户及时间信息
            position.setVersion(Constants.VERSION_INIT_VALUE);
            position.setId(positionService.getKey());
            String[] checkedOrgs = ServletRequestUtils.getStringParameters(request, "checkedOrgs");
            String[] positionLevels = ServletRequestUtils.getStringParameters(request, "positionLevels");
            positionService.save(position,checkedOrgs,positionLevels);

            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            modelMap.addAttribute(Constants.DEFAULT_ID_KEY, position.getId());
            logger.info(messages.getMessage("log.info.create", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain),
                    position.getId().toString()}));
        }
        catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.create", new String[] { securityUtils.getUserFullName(), messages.getMessage(domain) }));
        }
        return modelMap;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String editPage() throws SaviorFrameworkException {
        return viewPrefix + "edit";
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
    public @ResponseBody
    ModelMap update(@PathVariable("id")String id, HttpServletRequest request) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            Position position = positionService.get(id);
            ServletRequestDataBinder binder = new ServletRequestDataBinder(position);
            binder.bind(request);
            securityUtils.setModifyEntity(position);
            position.setVersion(position.getVersion()+1);

            String[] checkedOrgs = ServletRequestUtils.getStringParameters(request, "checkedOrgs");
            String[] positionLevels = ServletRequestUtils.getStringParameters(request, "positionLevels");

            positionService.update(position,checkedOrgs,positionLevels);
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            logger.info(messages.getMessage("log.info.edit",
                    new String[] { securityUtils.getUserFullName(), messages.getMessage(domain), id}));
        }
        catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.edit",
                    new String[] { securityUtils.getUserFullName(), messages.getMessage(domain), id }));
        }
        return modelMap;
    }

    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @ResponseBody
    public ModelMap delete(@RequestParam(value = "ids", required = true) String[] ids) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            positionService.deleteByIds(ids);
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            logger.info(messages.getMessage("log.info.delete", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain),
                    StringUtils.arrayToDelimitedString(ids, "|")}));
        }
        catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.delete", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain),
                    StringUtils.arrayToDelimitedString(ids, "|")}));
        }
        return modelMap;
    }

    @RequestMapping(value = "/org", method = RequestMethod.GET)
    @ResponseBody
    public void getOrgTree(HttpServletRequest request,HttpServletResponse response) throws SaviorFrameworkException, IOException {
        JSONArray array = new JSONArray();
        String id = request.getParameter("id");
        if(org.apache.commons.lang.StringUtils.isEmpty(id)){
            id=securityUtils.getUser().getOrg().getId();
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id", securityUtils.getUser().getOrg().getId());
            map.put("name", securityUtils.getUser().getOrg().getName());
            map.put("pId", null);
            map.put("pName", null);
            map.put("children", orgService.findByParent(id));
            array.add(map);
        }
        else{
            List<Map<String, Object>> list = orgService.findByParent(id);
            array = JSONArray.parseArray(JSONArray.toJSONString(list));
        }
        response.getWriter().write(array.toString());
    }


    @RequestMapping(value = "/{position}/org", method = RequestMethod.GET)
    @ResponseBody
    public void getOrgTree(HttpServletRequest request,
                           HttpServletResponse response,
                           @PathVariable("position") String position)
            throws SaviorFrameworkException, IOException {
        JSONArray array = new JSONArray();
        String id = request.getParameter("id");
        if(org.apache.commons.lang.StringUtils.isEmpty(id)){
            id=securityUtils.getUser().getOrg().getId();
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id", securityUtils.getUser().getOrg().getId());
            map.put("name", securityUtils.getUser().getOrg().getName());
            map.put("pId", null);
            map.put("pName", null);
            map.put("checked",orgService.checkOrgRelPosition(id,position));
            map.put("children", orgService.findByPosition(id, position));
            array.add(map);
        }
        else{
            List<Map<String, Object>> list = orgService.findByPosition(id, position);
            array = JSONArray.parseArray(JSONArray.toJSONString(list));
        }
        response.getWriter().write(array.toString());
    }

    @RequestMapping(value = "/role", method = RequestMethod.GET)
    public String role() throws SaviorFrameworkException {
        return viewPrefix + "role";
    }

    @RequestMapping(value = "/{position}/role/datagrid", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap role(@PathVariable("position") String position) {
        ModelMap modelMap = new ModelMap();
        try {
            modelMap.addAttribute(Constants.DEFAULT_RECORD_MODEL_KEY, roleService.findByPosition(position));
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }

    @RequestMapping(value = "/{position}/role", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap role(@PathVariable("position")String positionId, HttpServletRequest request) {
        ModelMap modelMap = new ModelMap();
        String[] roleIds = request.getParameterValues("ids");
        try {
            positionService.savePositionRole(positionId, roleIds);
            modelMap.addAttribute("success", Boolean.TRUE);
        }
        catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }

    @RequestMapping(value = "/view/{id}", method = RequestMethod.GET)
    @ResponseBody
    public ModelMap get(@PathVariable("id") String id) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            modelMap.addAttribute(Constants.DEFAULT_RECORD_MODEL_KEY, positionService.findById(id));
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        }
        catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(Constants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(Constants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }
}
